﻿using System;
using System.Collections.Generic;
using System.Text;

namespace SharpSoft.Geometries
{
    /// <summary>
    /// 表示一个弧度制数据
    /// </summary>
    public struct Radian
    {
        private double radian;
        public Radian(double r)
        {
            radian = r;
        }
        public static implicit operator double(Radian r)
        {
            return r.radian;
        }
        public static explicit operator Radian(double r)
        {
            return new Radian(r);
        }
        /// <summary>
        /// 将弧度转换为角度
        /// </summary>
        /// <param name="r"></param>
        public static explicit operator Degree(Radian r)
        {
            return new Degree(r.radian * 180 / Math.PI);
        }
        public static bool operator >(Radian r1, Radian r2)
        {
            return r1.radian > r2.radian;
        }
        public static bool operator >=(Radian r1, Radian r2)
        {
            return r1.radian >= r2.radian;
        }
        public static bool operator <(Radian r1, Radian r2)
        {
            return r1.radian < r2.radian;
        }
        public static bool operator <=(Radian r1, Radian r2)
        {
            return r1.radian <= r2.radian;
        }
        public static bool operator ==(Radian r1, Radian r2)
        {
            return r1.Equals(r2);
        }
        public static bool operator !=(Radian r1, Radian r2)
        {
            return !r1.Equals(r2);
        }
        public static Radian operator +(Radian r1, Radian r2)
        {
            return new Radian(r1.radian + r2.radian);
        }
        public static Radian operator -(Radian r1, Radian r2)
        {
            return new Radian(r1.radian - r2.radian);
        }

        private const double d_PI = Math.PI * 2;
        /// <summary>
        /// 将弧度优化在圆周内
        /// </summary>
        /// <returns></returns>
        public Radian Optimize2PI()
        {
            var o = this.radian % d_PI;
            if (o < 0)
            {
                o += d_PI;
            }
            return new Radian(o);
        }

        public override bool Equals(object obj)
        {
            if (obj is Radian r)
            {
                return r.radian == this.radian;
            }
            else if (obj is Degree d)
            {
                return this.Equals((Radian)d);
            }
            else if (obj is double dou)
            {
                return this.radian == dou;
            }
            return false;
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override string ToString()
        {
            return $"{Math.Round(radian / Math.PI, 3)}×Π";
        }
    }
}
